<?php
// +----------------------------------------------------------------------
// | Bwsaas
// +----------------------------------------------------------------------
// | Copyright (c) 2015~2020 http://www.buwangyun.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Gitee ( https://gitee.com/buwangyun/bwsaas )
// +----------------------------------------------------------------------
// | Author: buwangyun <hnlg666@163.com>
// +----------------------------------------------------------------------
// | Date: 2020-9-28 10:55:00
// +----------------------------------------------------------------------

namespace app\manage\controller\admin;

use app\common\model\MiniappThirdTemplate;
use buwang\base\AdminBaseController;
use buwang\facade\WechatMp;
use buwang\service\MiniappService;
use buwang\traits\CrudControllerTrait;
use think\facade\Db;
use think\facade\View;
use app\manage\model\admin\MiniappModule;
use think\facade\Request;
use think\Response;

class Miniapp extends AdminBaseController
{
    use CrudControllerTrait;

    protected $model = null;//模型实例

    protected function initialize()
    {
        parent::initialize();

        $this->model = new \app\common\model\Miniapp();
    }

    /**
     * 查看
     */
    public function index()
    {
        if (request()->isAjax()) {
            //同步第三方平台代码模板库到表bw_miniapp_third_template
            if (request()->param('action') == 'syncTemplate') {
                $tempLocal = MiniappThirdTemplate::column('template_id');
                if (!$tempLocal) $tempLocal = [];
                $tempRemote = WechatMp::getOpenPlatform()->code_template->list();
                $tempRemoteData = [];
                if (count($tempRemote['template_list']) > 0) {
                    foreach ($tempRemote['template_list'] as $k => $v) {
                        array_push($tempRemoteData, $v['template_id']);
                    }
                }
                $diff = array_diff($tempRemoteData, $tempLocal);
                $updateData = [];//组装需要更新的数据
                $delDataId = array_values(array_diff($tempLocal, $tempRemoteData));//组装需要更新的数据
                foreach ($diff as $k => $v) {
                    array_push($updateData, $tempRemote['template_list'][$k]);
                }
                $where = 'template_id in(' . implode(',', $delDataId) . ')';
                if ($tempRemote && isset($tempRemote['errcode'])) {
                    switch ($tempRemote['errcode']) {
                        case 0:
                            if (count($delDataId) > 0) MiniappThirdTemplate::where($where)->delete();
                            if (count($updateData) > 0) (new MiniappThirdTemplate)->saveAll($updateData);
                            return $this->success('代码模板库同步成功！增加：' . count($updateData) . '条，删除：' . count($delDataId) . '条');
                            break;
                        case 85064:
                            return $this->error('找不到模板！');
                            break;
                        case -1:
                            return $this->error('系统繁忙！');
                            break;
                        default:
                            return $this->error($tempRemote['errmsg']);
                            break;
                    }
                }
            }
            //已安装应用列表
            $list = $this->model
                ->withCount(['memberApp'])
                ->order('id asc')
                ->select()->toArray();
            //所有应用列表 除去系统目录
            //系统目录
            $system_dir = ['api', 'common', 'home', 'manage', 'database'];
            $dirs = array_diff(array_map('basename', glob(root_path() . 'app/' . '*', GLOB_ONLYDIR)), $system_dir);

            // 应用的目录列表
            $apps = array_column($list,null,'dir');
            //遍历应用列表
            foreach ($dirs as $key => $name) {
                $version = MiniappService::getVersion($name);
                if (!$version) continue;
                //没有安装过
                if (!isset($apps[$name])) {

                    $version['dir'] = $name;
                    $version['template_id'] = 0;
                    $version['sell_price'] = 0;
                    $version['market_price'] = 0;
                    $version['expire_day'] = 0;
                    $version['logo_image'] = root_path() . DS . 'app'. DS .$name. DS .'install'. DS .'static'. DS .'logo.png'??'';
                    $version['qrcode_image'] = '';
                    $version['style_images'] = '';
                    $version['status'] = -1;
                    $version['sort'] = 0;
                    $version['create_time'] = 0;
                    $version['update_time'] = 0;
                    //租户使用数
                    $version['member_use_count'] = 0;
                    $list[] = $version;
                } else {
                    foreach ($list as $k => $v) {
                        if ($v['dir'] == $name) {
                            $list[$k]['version'] = $version['version'];
                            if (!strstr($v['logo_image'], 'http')) {//应用未安装
                                $list[$k]['logo_image'] = bw_config('web_config.web_url') . '/' . $v['logo_image'];
                            }
                        }
                    }
                }

            }
            $data = compact('list');
            return $this->success('success', $data);
        }
        return view();
    }

    /**
     * 安装应用
     * @param string $dir
     */
    public function install($dir = '')
    {
        if (request()->isPost()) {
            $dir = $dir ? $dir : request()->post("dir/s");
            if (!$dir) return $this->error('应用名有误');
            Db::startTrans();
            try {
                MiniappService::install($dir);
                Db::commit();
            } catch (\Exception $e) {
                Db::rollback();
                return $this->error('出错了：' . $e->getMessage());
            }
            return $this->success("恭喜您，安装成功！");
        }
    }

    /**
     * 安装应用菜单节点.
     *
     * @param string $dir
     *
     * @return \think\Response
     */
    public function createMenu(string $dir = ''):Response {
        $dir = $dir ? : request()->param("dir/s");
        if (!$dir) {
            return $this->error('应用名有误');
        }
        Db::startTrans();
        try {
            MiniappService::createAppMenu($dir);
            Db::commit();
        } catch (\Exception $e) {
            Db::rollback();

            return $this->error('安装失败：' . $e->getMessage());
        }

        return $this->success("安装成功");
    }

    /**
     * 卸载应用
     * @param string $dir
     * @param boolean $force
     */
    public function uninstall($dir = '', $force = false)
    {
        if (request()->isPost()) {
            $dir = $dir ? $dir : request()->post("dir/s");
            if (!$dir) return $this->error('应用名不能为空');
            $force = boolval($this->request->post('force'));
            $this->model->startTrans();
            try {
                MiniappService::uninstall($dir, $force);

                $this->model->commit();
            } catch (\Throwable $e) {
                $this->model->rollback();
                return $this->error($e->getMessage());
            }
            return $this->success("卸载成功！");
        }
    }

    /**
     * 编辑
     * @menu true
     * @param int $id
     */
    public function edit($id = 0)
    {
        if(!$id){
            $id = request()->param('id', 0);
        }
        $row = $this->model->find($id);
        if (request()->isAjax()) {
            if (!$row) return $this->error('数据不存在'.$id);
            if (request()->isGet()) {
                //查询租户
                $members = \app\common\model\Member::field('id as value, nickname as title')->where('parent_id', 0)->select()->toArray();
                return $this->success('success', compact('row', 'members'));
            }
            if (request()->isPost()) {
                $param = Request::only(['content', 'describe', 'dir', 'diy_member_ids', 'expire_day', 'file', 'is_alipay_pay', 'is_diy', 'is_manage', 'is_openapp', 'is_tt_wechat_pay', 'is_wechat_pay', 'label', 'logo_image', 'qrcode_image', 'sort', 'status', 'style_images', 'title', 'types', 'open_url']);;
                if ($param['status'] == 1) {
                    //如果开启了售卖状态，判断是否配置了套餐
                    $miniappModuleCount = MiniappModule::where('miniapp_id', $row['id'])->count();
                    if (!$miniappModuleCount) {
                        return $this->error('未设置售卖套餐，请先去设置售卖套餐');
                    }
                }
                if (isset($param['diy_member_ids']) && is_array($param['diy_member_ids'])) {
                    $param['diy_member_ids'] = ',' . implode(',', $param['diy_member_ids']) . ',';
                }
                if (isset($param['types']) && is_array($param['types'])) {
                    $param['types'] = implode(',', $param['types']);
                }

                $this->model->startTrans();
                try {
                    $row->save($param);
                    $this->model->commit();
                } catch (\Exception $e) {
                    $this->model->rollback();
                    return $this->error('编辑失败' . $e->getMessage(), ['errorMsg' => $e->getMessage()]);
                }
                return $this->success('编辑成功');
            }

        } else {
            if (!$row) return $this->error_jump('数据不存在');
            View::assign('row', $row);
            //查询租户
            $members = \app\common\model\Member::field('id as value, nickname as title')->where('parent_id', 0)->select();
            View::assign('members', json_encode($members));
            return view();
        }
    }


    /**
     * 检测更新
     * @param string $dir
     */
    public function update($dir = '')
    {
        if (request()->isPost()) {
            if (!$dir) return $this->error('应用名有误');
            $check = request()->post("check/d", 0); //版本检测
            $miniappUpdateService = app('buwang\service\MiniappUpdateService'); //应用更新服务类
            if ($check) return $this->success('查询成功', $miniappUpdateService->info($dir)); //查询是否需要更新
            //调用更新
            $res = $miniappUpdateService->cover($dir); //TODO 应用覆盖更新：涉及io操作多，该方法执行时间会较长
            return $this->success('更新完成', $res);
        }
        return view();
    }
}
